#!/bin/python
# -*- coding: gb2312; mode:python ; tab-width:4 -*- ex:set tabstop=4 shiftwidth=4 expandtab: -*-

##########################################################
# PROJECT :
# FILE    : service thread.py
# CREATION: 2007-06-06
# LICENSE : GPL
# $Id: service_thread.py 1 2007-08-21 02:28:02Z hf $
##########################################################
"""
Python Script

Object: Thread to run asyncore and log_source
Usage : thread
Author: Wei Huangfu
Date  : 2007-06-06
"""

import struct
def ascii2hex(s):
    return '\\x'+'\\x'.join([binascii.b2a_hex(x) for x in s])   
class Struct(object):
    def pack(self, fmt, value):
        method_name = 'pack_' + str(fmt)
        try:
            method = getattr(self, method_name)
        except AttributeError:
            raise
        else:
            return method(value)

    def unpack(self, fmt, s):
        method_name = 'unpack_' + str(fmt)
        try:
            method = getattr(self, method_name)
        except AttributeError:
            raise
        else:
            return method(s)
            
    #calcsize: it is not needed, unpack will try use the first proper number of bytes

    def pack_uint8(self, v): return struct.pack(">B",v)
    def pack_uint16(self, v): return struct.pack(">H",v)
    def pack_uint32(self, v): return struct.pack(">I",v)
    def pack_uint8_be(self, v): return struct.pack(">B",v)
    def pack_uint16_be(self, v): return struct.pack(">H",v)
    def pack_uint32_be(self, v): return struct.pack(">I",v)
    def pack_uint8_le(self, v): return struct.pack("<B",v)
    def pack_uint16_le(self, v): return struct.pack("<H",v)
    def pack_uint32_le(self, v): return struct.pack("<I",v)

    def unpack_uint8(self, v):
        try:
            return struct.unpack(">B",v[:1])[0]
        except:
            print "~~~~~~~~~~~in wtsstruct,unpack_uint 8:v:",binascii.b2a_hex(v)
            print "~~~~~~~~~~~in wtsstruct,unpack_uint 8:v[:1]:",binascii.b2a_hex(v[:1])
            
    def unpack_uint16(self, v):
        try:
            return struct.unpack(">H",v[:2])[0]
        except:
            print "~~~~~~~~~~~in wtsstruct,unpack_uint 16:v:",binascii.b2a_hex(v)
            print "~~~~~~~~~~~in wtsstruct,unpack_uint 16:v[:2]:",binascii.b2a_hex(v[:2])
            
    def unpack_uint32(self, v): return struct.unpack(">I",v[:4])[0]
    def unpack_uint8_be(self, v): return struct.unpack(">B",v[:1])[0]
    def unpack_uint16_be(self, v): return struct.unpack(">H",v[:2])[0]
    def unpack_uint32_be(self, v): return struct.unpack(">I",v[:4])[0]
    def unpack_uint8_le(self, v): return struct.unpack("<B",v[:1])[0]
    def unpack_uint16_le(self, v): return struct.unpack("<H",v[:2])[0]
    def unpack_uint32_le(self, v): return struct.unpack("<I",v[:4])[0]
    def unpack_string(self,v):return v
    def unpack_binary(self, v): 
        #print str(ascii2hex(str(v)))
        return v
    def unpack_char_neighour_list(self, v):
        t = "".join([str(struct.unpack('>HB',v[i*3:i*3+3])) for i in range(len(v)/3)])
        return t
    def unpack_char_neighour_list_le(self, v):
        t = "".join([str(struct.unpack('<HB',v[i*3:i*3+3])) for i in range(len(v)/3)])
        return t
    def unpack_char_neighour_list16_le(self,v):
        t = "".join([str(struct.unpack('<HH',v[i*4:i*4+4])) for i in range(len(v)/4)])
        return t
    def unpack_char_neighour_list16(self,v):
        t = "".join([str(struct.unpack('>HH',v[i*4:i*4+4])) for i in range(len(v)/4)])
        return t
# test
if __name__ == "__main__":
    st = Struct()
    s = st.pack("uint32", 10000) + "xxx"
    print st.pack("char", 100)
    assert st.unpack("uint32",s)==10000
